﻿using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using StackExchange.Redis;

namespace xBei.Redis.Extension {
    public partial class RedisClient {

        /// <summary>
        /// 订阅（并发处理）
        /// </summary>
        /// <param name="name"></param>
        /// <param name="handler"></param>
        /// <returns></returns>
        public async Task<RedisClient> SubScribeAsync(string name, Action<RedisChannel, RedisValue> handler) {
            await (await GetSubscriberAsync()).SubscribeAsync(RedisChannel.Literal(name), handler);
            return this;
        }
        /// <summary>
        /// 取消订阅（并发处理）
        /// </summary>
        /// <param name="name"></param>
        /// <param name="handler"></param>
        /// <returns></returns>
        public async Task<RedisClient> UnSubScribeAsync(string name, Action<RedisChannel, RedisValue>? handler = null) {
            await (await GetSubscriberAsync()).UnsubscribeAsync(RedisChannel.Literal(name), handler, CommandFlags.FireAndForget);
            return this;
        }

        /// <summary>
        /// 订阅（顺序处理）
        /// </summary>
        /// <param name="name"></param>
        /// <param name="handler"></param>
        /// <returns></returns>
        public async Task<RedisClient> SubScribeAsync(string name, Func<ChannelMessage, Task> handler) {
            var channel = await (await GetSubscriberAsync()).SubscribeAsync(RedisChannel.Literal(name));
            channel.OnMessage(handler);
            return this;
        }

        /// <summary>
        /// 发布
        /// </summary>
        /// <param name="name"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public async Task<RedisClient> PublishAsync(string name, RedisValue message) {
            await (await GetSubscriberAsync()).PublishAsync(RedisChannel.Literal(name), message);
            return this;
        }
        /// <summary>
        /// 发布
        /// </summary>
        /// <param name="name"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public async Task<RedisClient> PublishAsync(string name, DateTime message) {
            await (await GetSubscriberAsync()).PublishAsync(RedisChannel.Literal(name), message.Ticks);
            return this;
        }
        /// <summary>
        /// 发布
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public async Task<RedisClient> PublishAsync<T>(string name, T message) where T : class, new() {
            await (await GetSubscriberAsync()).PublishAsync(RedisChannel.Literal(name), message.Serialize());
            return this;
        }
    }
}
